nginxにリバースプロキシ設定してapacheと連携させる
はじめに
railsとwebサーバを連携する場合はapache × passengerまたはnginx × unicornのどちらかを使用することが多いかと思います。 昔はwebサーバといえばapacheでしたが、最近はかなりnginxが使われてきています。 apacheとnginxのを比較したときに、静的ファイルはnginxが動的ファイルはapacheが早いと言われています。 そこで今回はnginxにリバースプロキシの設定をし、apacheと連携してみました。つまりhtmlや画像などの静的ファイルはnginxで処理し、railsの処理はapache経由で処理させることをやってみました。
開発環境
今回はmacのvirtual boxにubuntuをインストールし環境を構築しました。
- ubuntu 12.04 32bit
- apache 2.2
- nginx 1.6
- ruby 2.00
- rails 4.1.0
※apache等は既にインストール済みとして進めます。
apache上でrailsを動かす
まず始めにrailsプロジェクトを作成してapache上で動作するようにします。
passengerとの連携
$ rails new rails_app
プロジェクトを作成したらGemfileに以下を追加しインストールします。
$ gem 'passenger'
$ bundle install
apacheモジュールのビルドとインストールをします。
$ passenger-install-apache2-module
実行するとこんなメッセージが表示されます。 Enterキー押して、次へすすみます。
Welcome to the Phusion Passenger Apache 2 module installer, v4.0.42. This installer will guide you through the entire installation process. It shouldn't take more than 3 minutes in total. Here's what you can expect from the installation process: 1. The Apache 2 module will be installed for you. 2. You'll learn how to configure Apache. 3. You'll learn how to deploy a Ruby on Rails application. Don't worry if anything goes wrong. This installer will advise you on how to solve any problems. Press Enter to continue, or Ctrl-C to abort.
選択をRubyのみにしてEnterキーを押すと、インストールが始まります。
Use <space> to select. If the menu doesn't display correctly, press '!' ‣ ⬢ Ruby ⬡ Python ⬡ Node.js ⬡ Meteor
インストールが完了すると以下のようなメッセージが表示されるので、コピーします。これは環境に依存するのでインストールした環境のものをコピーしてください。 Enterキーを押すとVirtualHostのサンプルが表示されて完了です。
LoadModule passenger_module /home/test/rails_projects/rails_app/vendor/bundle/ruby/2.0.0/gems/passenger-4.0.42/buildout/apache2/mod_passenger.so <IfModule mod_passenger.c> PassengerRoot /home/test/rails_projects/rails_app/vendor/bundle/ruby/2.0.0/gems/passenger-4.0.42 PassengerDefaultRuby /home/test/.rbenv/versions/2.0.0-p451/bin/ruby </IfModule>
apache.confの設定
/etc/apache2/apache.confを開きます。(RedHat系ならhttpd.confになります) 先ほどコピーしたpassengerの設定を貼付けて保存します。 次にVirtualHostの設定をします。 /etc/apache2/sites-availableにlocalhostファイルを作成します。(ファイル名は任意です。) 以下、VirtualHostの設定です。nginxと連携させるポートをここでは8080にしています。ドキュメントルートはrailsプロジェクトのpublicを指定します。
<VirtualHost *:8080> DocumentRoot /home/test/rails_projects/rails_app/public RailsEnv development <Directory /home/test/rails_projects/rails_app/public> AllowOverride all Options -MultiViews </Directory> </VirtualHost>
設定を有効にさせます。localhostは作成したファイル名です。
sudo a2ensite localhost
ポートの設定を変更します。 /etc/apache2/ports.confを開いて8080に設定を変更します。
NameVirtualHost *:8080 Listen 8080
apacheを起動させます。
sudo apache2ctl start
これでhttp://localhost:8080にアクセスするとrailsのトップ画面(Welcome aboard)が表示されます。
nginxの設定
次にnginxにリバースプロキシの設定をします。 /etc/nginx/conf.d/にsample.confを作成します。(ファイル名は任意です)
upstream web-apache { server localhost:8080; } server { listen 80; server_name sample.jp; location ~* .*\.(jpg|gif|png|css|js|html|) { root /home/test/rails_projects/sample_app/public; index index.html index.htm; } location / { proxy_pass http://web-apache/; } }
静的ファイルのjpgなどのリクエストはnginxがそれ以外のリクエストはapacheのlocalhost:8080を呼び出すようにしています。 nginxを起動します。
sudo nginx
http://localhostにアクセスしてみます。railsのトップページが表示されます。 これでnginxとapacheが連携できました。
アクセスログを見てみる
macからubuntuにアクセスした後にapacheのアクセスログを見てみると・・・
sample.jp:8080 127.0.0.1 - - [29/May/2014:12:49:55 +0900] "GET /home/ HTTP/1.0"
127.0.0.1となっておりローカルからのアクセス、つまりnginxからアクセスしたIPになってしまいます。 これを解決するにはapacheにモジュールを追加する必要があります。解決してくれるモジュールはいくつかあるのですが、ここではmod-rpafを使用します。インストールしましょう。
sudo apt-get install libapache2-mod-rpaf
インストールが完了したらnginxの設定をします。先ほど作成したsample.confにproxy_set_headerの設定を追加します。
upstream web-apache { server localhost:8080; } server { listen 80; server_name sample.jp; location ~* .*\.(jpg|gif|png|css|js|html|) { root /home/test/rails_projects/sample_app/public; index index.html index.htm; } location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $http_host; proxy_pass http://web-apache/; } }
nginxを再起動して再度アクセスログを確認するとクライアントのIPにかわっていることが確認できます。
sample.jp:8080 192.168.1.38 - - [29/May/2014:13:50:55 +0900] "GET /home/ HTTP/1.0"
まとめ
リバースプロキシを設定すること負荷分散させることが出来たり、色々なメリットがあります。 新規でサイトを構築する際は検討してみてはいかがでしょうか。